<?php
/**
 * quick_curd
 * ============================================================================
 * 版权所有 2024-2099 www.wltx666.com，并保留所有权利。
 * 网站地址: https://www.wltx666.com
 * ============================================================================
 * Author: 草上飞
 * Email: wei@alipay16.cn
 * QQ: 2719875001
 * Date: 2025/10/29
 * 描述:
 */

namespace update;


class DiffRenderer
{
    // 生成差异
    public static function render($fromFile, $toFile)
    {
        // 读取文件内容，保留空行但移除换行符
        $fromLines = file($fromFile, FILE_IGNORE_NEW_LINES);
        $toLines = file($toFile, FILE_IGNORE_NEW_LINES);

        // 使用更简单的逐行比较算法
        $diff = self::lineDiff($fromLines, $toLines);
        
        return $diff;
    }

    /**
     * 简单但有效的行差异算法
     */
    private static function lineDiff($fromLines, $toLines)
    {
        $diff = [];
        $i = 0;
        $j = 0;
        
        // 逐行比较
        while ($i < count($fromLines) || $j < count($toLines)) {
            // 如果两个文件都还有行未处理
            if ($i < count($fromLines) && $j < count($toLines)) {
                // 如果当前行相同
                if ($fromLines[$i] === $toLines[$j]) {
                    $diff[] = [' ', $fromLines[$i]];
                    $i++;
                    $j++;
                    continue;
                }
                
                // 查找是否在目标文件中后面有匹配的行
                $foundInTo = false;
                for ($k = $j + 1; $k < min($j + 10, count($toLines)); $k++) {
                    if ($fromLines[$i] === $toLines[$k]) {
                        // 在目标文件中找到匹配，说明中间添加了行
                        for ($l = $j; $l < $k; $l++) {
                            $diff[] = ['+', $toLines[$l]];
                        }
                        $diff[] = [' ', $fromLines[$i]];
                        $i++;
                        $j = $k + 1;
                        $foundInTo = true;
                        break;
                    }
                }
                
                if ($foundInTo) continue;
                
                // 查找是否在源文件中后面有匹配的行
                $foundInFrom = false;
                for ($k = $i + 1; $k < min($i + 10, count($fromLines)); $k++) {
                    if ($toLines[$j] === $fromLines[$k]) {
                        // 在源文件中找到匹配，说明中间删除了行
                        for ($l = $i; $l < $k; $l++) {
                            $diff[] = ['-', $fromLines[$l]];
                        }
                        $diff[] = [' ', $toLines[$j]];
                        $i = $k + 1;
                        $j++;
                        $foundInFrom = true;
                        break;
                    }
                }
                
                if ($foundInFrom) continue;
                
                // 如果都没有找到匹配，认为是修改了这一行
                $diff[] = ['-', $fromLines[$i]];
                $diff[] = ['+', $toLines[$j]];
                $i++;
                $j++;
                continue;
            }
            
            // 处理剩余的行
            if ($i < count($fromLines)) {
                $diff[] = ['-', $fromLines[$i]];
                $i++;
            } else if ($j < count($toLines)) {
                $diff[] = ['+', $toLines[$j]];
                $j++;
            }
        }
        
        return $diff;
    }

    public static function format($diff, $context = 3)
    {
        // 检查是否有实际的变更（新增或删除的行）
        $hasChanges = false;
        foreach ($diff as $line) {
            if ($line[0] === '+' || $line[0] === '-') {
                $hasChanges = true;
                break;
            }
        }
        
        // 如果没有实际变更，显示提示信息
        if (!$hasChanges) {
            $output = '<div class="diff-container">';
            $output .= '<div class="diff-header">文件差异对比</div>';
            $output .= '<div class="diff-content">';
            $output .= '<div style="padding: 20px; text-align: center; color: #666; font-style: italic;">';
            $output .= '文件已被标记为修改，但内容无实际变更（可能是时间戳或权限变更）';
            $output .= '</div>';
            $output .= '</div>'; // .diff-content
            $output .= '</div>'; // .diff-container
            return $output;
        }

        $output = '<div class="diff-container">';
        $output .= '<div class="diff-header">文件差异对比</div>';
        $output .= '<div class="diff-content">';
        
        $oldLine = 0;
        $newLine = 0;
        
        foreach ($diff as $idx => $line) {
            $type = $line[0];
            $content = isset($line[1]) ? $line[1] : '';
            
            // 更新行号
            if ($type === ' ' || $type === '-') {
                $oldLine++;
            }
            if ($type === ' ' || $type === '+') {
                $newLine++;
            }
            
            // 根据类型设置CSS类和行号显示
            switch ($type) {
                case '+':
                    $cssClass = 'diff-line diff-line-add';
                    $lineNumbers = '<span class="diff-line-number"></span><span class="diff-line-number">' . $newLine . '</span>';
                    // 添加 "+" 符号前缀，就像 Git 一样
                    $content = '+ ' . $content;
                    break;
                case '-':
                    $cssClass = 'diff-line diff-line-del';
                    $lineNumbers = '<span class="diff-line-number">' . $oldLine . '</span><span class="diff-line-number"></span>';
                    // 添加 "-" 符号前缀，就像 Git 一样
                    $content = '- ' . $content;
                    break;
                default: // ' ' (空格表示无变化)
                    $cssClass = 'diff-line diff-line-nor';
                    $lineNumbers = '<span class="diff-line-number">' . $oldLine . '</span><span class="diff-line-number">' . $newLine . '</span>';
                    // 添加空格前缀以对齐
                    $content = '  ' . $content;
                    break;
            }
            
            $output .= '<div class="' . $cssClass . '">' . $lineNumbers . htmlspecialchars($content) . '</div>';
        }
        
        $output .= '</div>'; // .diff-content
        $output .= '</div>'; // .diff-container
        
        return $output;
    }
}